import os
import sys
from functools import reduce

"""
a1:  区间值模糊数 格式为([],[])

self.q: q值

a2:     区间值模糊数 格式为([],[])

编写时间:2022-6-30 
编写人:吴卓成
参考文献:Neural Computing and Applications
"""


from Utilities.AutoGetOperator.selectPackage import get_func


Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class NeutralAverage(Operator_IVQ_ROFS):

    def hesitation(self,a1):
        u_f,u_r,v_f,v_r=*a1[0],*a1[1]
        h_f=(1-(u_r**self.q)-(v_r**self.q))**(1/self.q)
        h_r=(1-(u_f**self.q)-(v_f**self.q))**(1/self.q)
        return h_f,h_r

    def add(self,a1,a2,q=0):
        '''

        :param a1:
        :param a2:
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        a1_hf,a1_hr=self.hesitation(a1)
        a2_hf,a2_hr=self.hesitation(a2)
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        u_f=((((u_1_f**q)+(u_2_f**q))/((u_1_f**q)+(v_1_f**q)+(u_2_f**q)+(v_2_f**q)))*(1-(a1_hr**q)*(a2_hr**q)))**(1/q)
        u_r=((((u_1_r**q)+(u_2_r**q))/((u_1_r**q)+(v_1_r**q)+(u_2_r**q)+(v_2_r**q)))*(1-(a1_hf**q)*(a2_hf**q)))**(1/q)
        v_f=((((v_1_f**q)+(v_2_f**q))/((u_1_f**q)+(v_1_f**q)+(u_2_f**q)+(v_2_f**q)))*(1-(a1_hr**q)*(a2_hr**q)))**(1/q)
        v_r=((((v_1_r**q)+(v_2_r**q))/((u_1_r**q)+(v_1_r**q)+(u_2_r**q)+(v_2_r**q)))*(1-(a1_hf**q)*(a2_hf**q)))**(1/q)
#     return ([u_f, u_r], [v_f, v_r])
        return ([u_f, u_r], [v_f, v_r])

    def mutil(self,a1,a2,q=0):
        '''

        :param a1:
        :param a2:
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        a1_hf,a1_hr=self.hesitation(a1)
        a2_hf,a2_hr=self.hesitation(a2)
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        u_f=((u_1_f*u_2_f)/((((u_1_f**q)*(u_2_f**q))+((v_1_f**q)*(v_2_f**q)))**(1/q)))*((1-(a1_hr**q)-(a2_hr**q))**(1/q))
        u_r=((u_1_r*u_2_r)/((((u_1_r**q)*(u_2_r**q))+((v_1_r**q)*(v_2_r**q)))**(1/q)))*((1-(a1_hf**q)-(a2_hf**q))**(1/q))
        v_f=((v_1_f*v_2_f)/((((u_1_f**q)*(u_2_f**q))+((v_1_f**q)*(v_2_f**q)))**(1/q)))*((1-(a1_hr**q)-(a2_hr**q))**(1/q))
        v_r=((v_1_r*v_2_r)/((((u_1_r**q)*(u_2_r**q))+((v_1_r**q)*(v_2_r**q)))**(1/q)))*((1-(a1_hf**q)-(a2_hf**q))**(1/q))
        return ([u_f, u_r], [v_f, v_r])

    def kmutil(self,a1,k=1,q=0):#要求大于1
        '''

        :param a1:
        :param k:
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        a1_hf,a1_hr=self.hesitation(a1)
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_f=((u_1_f**k)/((((u_1_f**q)**k)+((v_1_f**q)**k))**(1/q)))*((1-((a1_hr**q)**k))**(1/q))
        u_r=((u_1_r**k)/((((u_1_r**q)**k)+((v_1_r**q)**k))**(1/q)))*((1-((a1_hf**q)**k))**(1/q))
        v_f=((v_1_f**k)/((((u_1_f**q)**k)+((v_1_f**q)**k))**(1/q)))*((1-((a1_hr**q)**k))**(1/q))
        v_r=((v_1_r**k)/((((u_1_r**q)**k)+((v_1_r**q)**k))**(1/q)))*((1-((a1_hf**q)**k))**(1/q))
        return ([u_f, u_r], [v_f, v_r])

    def pow(self,a1,k=1,q=0):
        '''

        :param a1:
        :param k:
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        a1_hf,a1_hr=self.hesitation(a1)
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_f=(((u_1_f**q)/((u_1_f**q)+(v_1_f**q)))*(1-((a1_hr**q)**k)))**(1/q)
        u_r=(((u_1_r**q)/((u_1_r**q)+(v_1_r**q)))*(1-((a1_hf**q)**k)))**(1/q)
        v_f=(((v_1_f**q)/((u_1_f**q)+(v_1_f**q)))*(1-((a1_hr**q)**k)))**(1/q)
        v_r=(((v_1_r**q)/((u_1_r**q)+(v_1_r**q)))*(1-((a1_hf**q)**k)))**(1/q)
        return ([u_f, u_r], [v_f, v_r])

class NeutralAverageA(NeutralAverage):
    def getResult(self, *waste1, **waste2):
        '''

        :param waste1:
        :param waste2:
        :return:
        '''

        data_list=self.data_list#获取数据
        res=self.kmulti(self.data_list[0],self.weight_list[0],self.q)#取出第一个W*AI为结果初始值
        data_list=data_list[1::]
        for index ,enum in enumerate(data_list,start=1):#enumerate 返回下标与对应值
            temp=self.kmulti(enum,self.weight_list[index],self.q)
            res=self.add(res,temp,self.q)
        return res

class NeutralAverageWA(NeutralAverage):
    def getResult(self, *waste1, **waste2):
        data_list=self.data_list#获取数据
        res=self.kmulti(self.data_list[0],self.weight_list[0],self.q)#取出第一个W*AI为结果初始值
        data_list=data_list[1::]#切片获取除去第一个元素以外的其他元素
        for index ,enum in enumerate(data_list,start=1):#enumerate 返回下标与对应值
            temp=self.kmulti(enum,self.weight_list[index],self.q)
            res=self.add(res,temp,self.q)
        return res

class NeutralAverageOWA(NeutralAverage):
    def getResult(self, *waste1, **waste2):
        data_list= self.sortdata()#根据得分函数排序,获取数据
        res=self.kmulti(self.data_list[0],self.weight_list[0],self.q)
        data_list=data_list[1::]
        for index ,enum in enumerate(data_list,start=1):
            temp=self.kmulti(enum,self.weight_list[index],self.q)
            res=self.add(res,temp,self.q)
        return res

class NeutralAverageWGA(NeutralAverage):
    def getResult(self, *waste1, **waste2):
        data_list= self.data_list
        res=self.pow(self.data_list[0],self.weight_list[0],self.q)
        data_list=data_list[1::]
        for index ,enum in enumerate(data_list,start=1):
            temp=self.pow(enum,self.weight_list[index],self.q)
            res=self.multi(res,temp,self.q)
        return res

class NeutralAverageGA(NeutralAverage):
    def getResult(self, *waste1, **waste2):
        data_list=self.data_list
        res=data_list[0]
        data_list=data_list[1::]
        for index ,enum in enumerate(data_list,start=1):
            res=self.multi(res,enum,self.q)
        return self.pow(res,1/self.q,self.q)    
#测试


if __name__ == '__main__':
    data_list=[([0.31, 0.24], [0.73, 0.72]), ([0.97, 0.12], [0.12, 0.05]),
    ([0.8, 0.52], [0.73, 0.15]), ([0.91, 0.49], [0.42, 0.47]),([0.95, 0.06], [0.19, 0.1])]
    weight_list=[0.1, 0.2, 0.3, 0.1, 0.3],
    Pa =NeutralAverageA(data_list)
    # Pa = GA(list1)
    # Pa = WA(list1,weight_list)
    # Pa = WGA(list1,weight_list)
    # Pa = OWA(list1,weight_list)
    print(Pa.getResult())




